package com.snow.java.base.junit;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * @类名称：
 * @类描述：
 * @author: bingHeng
 * @Date 2019.04.11
 * @Version: 1.0
*/
public class MyDateTime1 {

    /**
     * java 8之前处理日期与时间都存在线程安全的问题，这里证明一下这个问题
     *
     * 控制台打印结果中出现了不一样的时间，则证明存在线程安全问题（建议多运行几遍），或者直接抛出异常
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        // 演示线程安全时解开注释即可
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");

        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        Callable<Date> task = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                    // 演示线程安全解开注释即可
//                return simpleDateFormat.parse("20180411");
                return DateFormatThreadLocal.convert("20180413");
            }
        };

        List<Future<Date>> futures = new ArrayList<>();

        for(int i = 0; i < 100; i++) {
            futures.add(executorService.submit(task));
        }

        for(Future<Date> future : futures) {
            System.out.println(future.get());
        }

        executorService.shutdown(); // 停
    }
}

/**
 * 解决传统Java 日期时间线程不安全的问题
 */
class DateFormatThreadLocal {
    private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMdd");
        }
    };

    public static Date convert(String source) throws ParseException {
        return df.get().parse(source);
    }
}
